var taskQueue = [
  {start: 'task1 start', end: 'task1 end'},
  {start: 'task2 start', end: 'task2 end'},
  {start: 'task3 start', end: 'task3 end'},
]
function sleep(delay) {
  for (let last = Date.now(); Date.now() - last <= delay; ) {}
}

function handler(taskInfo) {
  console.log(taskInfo.start+':'+ new Date().toLocaleString())
  console.log('task doing something....')
  sleep(500)
  console.log(taskInfo.end)
}

function workLoop(deadline) {
  console.log('空闲时间剩余:'+deadline.timeRemaining())
  if (deadline.didTimeout) {
    console.log('超时执行:'+deadline.didTimeout)
  }
  // 空闲时间足够，则一循环执行
  while((deadline.timeRemaining() > 0 || deadline.didTimeout) && taskQueue.length) {
    handler(taskQueue.shift())
  }
  // 空闲耗尽，则等待下次空闲
  if (taskQueue.length) {
    window.requestIdleCallback(workLoop, { timeout: 1000 })
  }
}
setTimeout(() => {
  window.requestIdleCallback(workLoop, { timeout: 1000 })
}, 3000)